原始题目:剑指 Offer 25. 合并两个排序的链表 (opens new window)

解题思路

使用双指针来解决这个问题。首先创捷一个伪头节点 headhead,使用 l1,l2l1, l2 分别指向两个链表,根据 l1.vall1.vall2.vall2.val 的大小关系添加到 headhead 链表上,两个指针交替前进,直到遍历完毕。

算法流程

  1. 创建伪头节点 headheadpp 指向 headhead
  2. 遍历 l1l1l2l2 直到其中一条链表遍历结束
    1. l1.val<l2.vall1.val < l2.valp.nextp.next 指向 l1l1l1l1 指向下一个节点。
    2. l1.vall2.vall1.val \geq l2.valp.nextp.next 指向 l2l2l2l2 指向下一个节点。
    3. pp 指向下一个节点。
  3. 合并剩余的尾部
    1. 如果 l1l1 不为 nullnull,那么 p.nextp.next 直接指向 l1l1
    2. 否则 p.nextp.next 指向 l2l2
  4. 返回 head.nexthead.next 即可。

代码:

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode head = new ListNode(-1);
    ListNode p = head;

    while(l1 != null && l2 != null) {
        if(l1.val < l2.val) {
            p.next = l1;
            l1 = l1.next;
        } else {
            p.next = l2;
            l2 = l2.next;
        }
        p = p.next;
    }
    p.next = l1 == null ? l2 : l1;
    return head.next;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

复杂度分析

  • 时间复杂度 O(m+n)O(m+n)mmnn 是两条链表各自的长度,合并操作需要遍历两链表。

  • 空间复杂度O(1)O(1):伪头节点 headheadpp 使用常数大小的空间。

上次更新: 2023/10/15